﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Core.Tools
{
    public class NameValueEnumerator : IDictionaryEnumerator
    {
        private static readonly Func<NameValueCollection, int, object> BaseGet;

        static NameValueEnumerator()
        {
            var BaseGetMethod = typeof(NameValueCollection).GetMethod("BaseGet", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(int) }, null);

            BaseGet = (Func<NameValueCollection, int, object>)Delegate.CreateDelegate(typeof(Func<NameValueCollection,int, object>), BaseGetMethod);
        }

        public NameValueEnumerator(NameValueCollection Content, bool MergeValue = false)
        {
            FirstContent = Content;
            this.MergeValue = MergeValue;

            Reset();
        }

        private readonly NameValueCollection FirstContent;
        private readonly bool MergeValue;

        private int FirstIndex;
        private int LastIndex;
        private ArrayList LastContent;

        public string Key { get { return FirstContent.GetKey(FirstIndex); } }

        public string Value
        {
            get
            {
                if (MergeValue)
                {
                    return FirstContent[FirstIndex];
                }
                else
                {
                    return (string)LastContent[LastIndex];
                }
            }
            set
            {
                if (MergeValue)
                {
                    LastContent.Clear();
                    LastContent.Add(value);
                }
                else
                {
                    LastContent[LastIndex] = value;
                }
            }
        }

        public KeyValuePair<string,string> Entry { get { return new KeyValuePair<string,string>(Key, Value); } }

        public object Current { get { return Value; } }

        public int Count
        {
            get
            {
                if (MergeValue)
                {
                    return FirstContent.Count;
                }
                else
                {
                    int Result = 0;

                    for (int i = 0; i < FirstContent.Count; i++)
                    {
                        Result += ((ArrayList)BaseGet(FirstContent, i)).Count;
                    }

                    return Result;
                }
            }
        }

        public bool MoveNext()
        {
            if (MergeValue)
            {
                goto AddFirstIndex;
            }

            ++LastIndex;

            if (LastContent != null && LastIndex < LastContent.Count)
            {
                return true;
            }

            LastIndex = 0;


            AddFirstIndex:

            ++FirstIndex;

            if (FirstIndex == FirstContent.Count)
            {
                return false;
            }

            LastContent = (ArrayList)BaseGet(FirstContent, FirstIndex);

            return true;
        }

        public void Reset()
        {
            FirstIndex = -1;
            LastIndex = -1;
            LastContent = null;
        }

        object IDictionaryEnumerator.Key { get { return Key; } }

        object IDictionaryEnumerator.Value { get { return Value; } }

        DictionaryEntry IDictionaryEnumerator.Entry { get { return new DictionaryEntry(Key, Value); } }
    }
}
